package eventbus

import (
	"gameServer/log" // 日志包，用于记录事件消费的详细信息，是事件消费者的核心输出目标
)

/*
本文件实现的事件消费者（EventConsumer），是事件总线（EventBus）的核心订阅者之一，
专门负责订阅并处理“游戏会话生命周期相关事件”（如会话创建、会话启动、玩家加入、会话结束），
通过统一记录结构化日志的方式，将这些关键操作的信息持久化/可视化，实现系统操作的可追溯性、可监控性。

它的核心价值是“解耦事件发布与事件处理”：
- 发布事件的模块（如gamesession.SessionManager、BaseSession）无需关心“谁要处理事件”，只需专注于“什么时候发布事件”；
- 事件消费者专注于“如何处理事件”（此处是记录日志），无需关心“事件是谁发布的”；
后续若需扩展事件处理逻辑（如添加监控告警、数据统计），只需新增订阅者，无需修改原有发布/消费代码。
*/

// EventConsumer 事件消费者结构体，用于订阅并处理特定类型的事件（此处聚焦会话相关事件）
// 持有EventBus实例，通过总线订阅事件，接收事件后执行预设处理逻辑（此处为日志记录）
type EventConsumer struct {
	eventBus EventBus // 事件总线实例，是消费者与事件发布者之间的“通信桥梁”
	// 核心作用：通过eventBus.Subscribe()方法订阅目标事件，当总线收到对应事件时，自动触发消费者的处理逻辑
}

// NewEventConsumer 创建事件消费者实例，建立消费者与事件总线的关联
// 参数：
//   eventBus: 系统全局的事件总线实例（通常由外部初始化后传入，确保整个系统使用同一总线，实现事件全局流通）
// 返回值：
//   *EventConsumer: 初始化后的事件消费者实例，此时尚未订阅任何事件，需调用Start()方法启动订阅
func NewEventConsumer(eventBus EventBus) *EventConsumer {
	return &EventConsumer{
		eventBus: eventBus, // 将外部传入的总线绑定到消费者，为后续订阅事件做准备
	}
}

// Start 启动事件消费者，核心逻辑是“订阅所有感兴趣的会话相关事件”，并注册对应的事件处理函数（回调函数）
// 调用此方法后，消费者会持续监听事件总线：当总线发布已订阅的事件时，自动执行对应的回调函数（记录日志）
func (c *EventConsumer) Start() {
	// -------------------------- 1. 订阅“会话创建”事件（EventSessionCreated） --------------------------
	// 事件含义：当gamesession.SessionManager成功创建一个新会话时，会通过eventBus.Publish()发布此事件
	// 订阅逻辑：调用eventBus.Subscribe(事件类型, 回调函数)，回调函数会在事件被发布时执行
	c.eventBus.Subscribe(EventSessionCreated, func(e Event) {
		// e是事件实例，通过e.Data()获取事件携带的业务数据（发布时传入的map[string]interface{}）
		// 类型断言：将e.Data()返回的interface{}转为map[string]interface{}，因为发布事件时约定数据格式为map
		data := e.Data().(map[string]interface{})

		// 从事件数据中提取关键信息，记录结构化日志
		// data["session_id"]：事件发布时传入的“新创建的会话ID”（如"session_001"）
		// data["config"]：事件发布时传入的“会话配置”（如SessionConfig{MaxPlayers:4, MinPlayers:2}）
		log.Infof(
			"EventConsumer: Session created - ID: %s, Config: %v", 
			data["session_id"],  // 会话唯一标识，用于定位具体会话
			data["config"],       // 会话的初始化配置，用于追溯会话的参数设置（如最大玩家数、是否自动启动）
		)
	})

	// -------------------------- 2. 订阅“会话启动”事件（EventSessionStarted） --------------------------
	// 事件含义：当游戏会话从“准备态（StateReady）”转为“运行态（StatePlaying）”时（如调用BaseSession.Start()成功），发布此事件
	c.eventBus.Subscribe(EventSessionStarted, func(e Event) {
		data := e.Data().(map[string]interface{})

		// 记录会话启动的关键信息：会话ID、启动时间
		// data["session_id"]：启动的会话ID
		// data["start_time"]：会话启动的时间戳（通常为time.Now()，如2024-05-20 15:30:00）
		log.Infof(
			"EventConsumer: Session started - ID: %s, StartTime: %v", 
			data["session_id"],  // 定位启动的会话
			data["start_time"] ,  // 记录启动时间，用于后续统计会话运行时长（结束时间-启动时间）
		)
	})

	// -------------------------- 3. 订阅“玩家加入”事件（EventPlayerJoined） --------------------------
	// 事件含义：当调用BaseSession.AddPlayer()成功将一个玩家加入会话时，发布此事件
	c.eventBus.Subscribe(EventPlayerJoined, func(e Event) {
		data := e.Data().(map[string]interface{})

		// 记录玩家加入的关键信息：目标会话ID、加入的玩家ID、加入后会话的总玩家数
		// data["session_id"]：玩家加入的会话ID
		// data["player_id"]：加入会话的玩家唯一标识（如"player_123"）
		// data["player_count"]：玩家加入后，会话内的总玩家数（如加入前1人，加入后2人，此处为2）
		log.Infof(
			"EventConsumer: Player joined - Session: %s, Player: %s, Count: %v", 
			data["session_id"],  // 定位玩家加入的会话
			data["player_id"],   // 定位具体加入的玩家
			data["player_count"], // 反映会话当前的玩家规模，判断是否达到启动条件（如MinPlayers=2）
		)
	})

	// -------------------------- 4. 订阅“会话结束”事件（EventSessionEnded） --------------------------
	// 事件含义：当调用BaseSession.End()成功将会话从“运行态”转为“结束态（StateFinished）”时，发布此事件
	c.eventBus.Subscribe(EventSessionEnded, func(e Event) {
		data := e.Data().(map[string]interface{})

		// 记录会话结束的关键信息：会话ID、会话总运行时长
		// data["session_id"]：结束的会话ID
		// data["total_duration"]：会话从启动到结束的总时长（如10分钟，格式通常为time.Duration类型）
		log.Infof(
			"EventConsumer: Session ended - ID: %s, Duration: %v", 
			data["session_id"],    // 定位结束的会话
			data["total_duration"], // 统计会话的有效运行时间，用于后续分析（如平均会话时长、异常短会话排查）
		)
	})

	// 记录消费者启动成功的日志，标识“消费者已就绪，开始监听事件”
	log.Info("EventConsumer started and subscribed to events")
}